package com.github.murzagalin.evaluator.ast

import com.github.murzagalin.evaluator.token.Operand
import com.github.murzagalin.evaluator.token.Operator

sealed class Expression {

    abstract fun visit(visitor: AstVisitor): Any

    data class Unary(
        val token: Operator,
        val expression: Expression
    ) : Expression() {
        override fun visit(visitor: AstVisitor) = visitor.visitUnary(this)
    }

    data class Binary(
        val token: Operator,
        val leftExpression: Expression,
        val rightExpression: Expression
    ) : Expression() {
        override fun visit(visitor: AstVisitor) = visitor.visitBinary(this)
    }

    data class Ternary(
        val token: Operator,
        val firstExpression: Expression,
        val secondExpression: Expression,
        val thirdExpression: Expression
    ) : Expression() {
        override fun visit(visitor: AstVisitor) = visitor.visitTernary(this)
    }

    data class FunctionCall(
        val token: com.github.murzagalin.evaluator.token.FunctionCall,
        val arguments: List<Expression>
    ) : Expression() {
        override fun visit(visitor: AstVisitor) = visitor.visitFunctionCall(this)
    }

    data class Terminal(
        val token: Operand
    ) : Expression() {
        override fun visit(visitor: AstVisitor) = visitor.visitTerminal(this)
    }
}


